华为OJ--------迷宫问题

题目描述

定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示:
    int maze[5][5] = {
        0, 1, 0, 0, 0,
        0, 1, 0, 1, 0,
        0, 0, 0, 0, 0,
        0, 1, 1, 1, 0,
        0, 0, 0, 1, 0,};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。

Input
    一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
Output
    左上角到右下角的最短路径,格式如样例所示。
Sample Input
    0 1 0 0 0
    0 1 0 1 0
    0 0 0 0 0
    0 1 1 1 0
    0 0 0 1 0
Sample Output
    (0, 0)
    (1, 0)
    (2, 0)
    (2, 1)
    (2, 2)
    (2, 3)
    (2, 4)
    (3, 4)
    (4, 4)

输入描述

输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

输出描述

左上角到右下角的最短路径,格式如样例所示。

输入例子

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出例子

(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)

(4,4)


import java.util.Scanner;  
import java.util.Stack;  
  
public class Main {  
    public static void main(String args[]){  
        Scanner sc=new Scanner(System.in);  
         while (sc.hasNext()) {  
             int m = sc.nextInt();  
             int n = sc.nextInt();  
             int[][] map = new int[m][n];//定义一个Map矩阵,用来保存地图  
             for (int i = 0; i < m; i++) {  
                 for (int j = 0; j < n; j++) {  
                     map[i][j] = sc.nextInt();//输入地图  
                 }  
             }  
             int[][] dir = {{1, 0}, {0, 1}};//定义两个方向横着走或者竖着走(题目中说只走这两个方向,当前也可以定义多个方向)  
             Stack<Node> stack = new Stack<Node>();//定义一个栈,保存路径  
             int[][] visited = new int[m][n];//标记是否被访问,这个要和Map大小对应  
             Node start = new Node(0, 0);//定义起始位置  
             Node end = new Node(m - 1, n - 1);//定义目的位置  
             visited[start.x][start.y] = 1;//将起始点标记为访问  
             stack.push(start);//将起始点加入队列  
             while (!stack.isEmpty()) {//如果对了为空了还没有找到解,说明就没有通路,当然本题不存在无解,题目上说了一定存在一个通路。  
                 boolean flag = false;//标记是否找了一个方向  
                 Node pek = stack.peek();//获取栈顶元素,注意不需要出栈  
                 if (pek.x == end.x && pek.y == end.y) {//如果到达目的地则跳出循环  
                     break;  
                 } else {  
                     for (int i = 0; i < 2; i++) {//循环两个方向  
                         Node nbr = new Node(pek.x + dir[i][0], pek.y + dir[i][1]);//找到当前位置的邻居位置坐标并判断是否合法  
                         if (nbr.x >= 0 && nbr.x < m && nbr.y >= 0 && nbr.y < n && map[nbr.x][nbr.y] == 0 && visited[nbr.x][nbr.y] == 0) {//判断邻居节点是否合法  
                             stack.push(nbr);//合法将邻居位置加入栈  
                             visited[nbr.x][nbr.y] = 1;//并标记该节点已经访问  
                             flag = true;//找到了一个方向  
                             break;//找到了就停止循环,顺着这个方向一直搜索  
                         }  
                     }  
                     if (flag) {//找到了方向,就不用执行下面的出栈,沿着这个方向一直搜下去  
                         continue;  
                     }  
                     stack.pop();//如果两个方向都不能通过,则出栈。  
                 }  
             }  
             Stack<Node> stkRev = new Stack<Node>();//将路径反过来,因为栈中输出的路径是反的  
             while (!stack.isEmpty()) {  
                 stkRev.push(stack.pop());  
             }  
             while (!stkRev.isEmpty()) {  
                  System.out.println("(" + stkRev.peek().x + "," + stkRev.peek().y + ")");  
                 stkRev.pop();  
             }  
         }  
    }  
}  
class Node{  
    int x;  
    int y;  
    Node(int x,int y){  
        this.x=x;  
        this.y=y;  
    }  
}






import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

/**
 * Author: 王俊超
 * Date: 2016-01-03 19:07
 * Declaration: All Rights Reserved !!!
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
//        Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
        while (scanner.hasNext()) {
            int row = scanner.nextInt();
            int col = scanner.nextInt();
            int[][] matrix = new int[row][col];
            for (int i = 0; i < row * col; i++) {
                matrix[i / col][i % col] = scanner.nextInt();
            }

            System.out.print(mazeWayfinding(matrix));
        }

        scanner.close();
    }

    private static String mazeWayfinding(int[][] matrix) {
        List<String> result = new ArrayList<>();
        boolean[][] visited = new boolean[matrix.length][matrix[0].length];
        boolean[] find = new boolean[1];
        wayfinding(matrix, 0, 0, visited, find, result);

        StringBuilder builder = new StringBuilder();
        for (String s : result) {
            builder.append(s).append('\n');
        }

//        return builder.substring(0, builder.length() - 1);
        return builder.toString();
    }

    /**
     * 找迷宫路径
     *
     * @param matrix  迷宫
     * @param x       当前的行号
     * @param y       当前的列号
     * @param visited 标记某个位置是否被访问过了
     * @param find    是否已经找到
     * @param result  路径标识
     */
    private static void wayfinding(int[][] matrix, int x, int y, boolean[][] visited, boolean[] find, List<String> result) {
        // 如果已经找到
        if (find[0]) {
            return;
        }

        // 位置超出了迷宫或者当前不置不可走,或者已经被访问过了
        if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length
                || matrix[x][y] == 1 || visited[x][y]) {
            return;
        }

        // 到达终点
        // 如果已经到达右下角,并且右下角的位置可以走
        if (x == matrix.length - 1 && y == matrix[0].length - 1 && matrix[x][y] == 0) {
            find[0] = true;
            visited[x][y] = true;
            // 添加坐标的
            result.add("(" + x + "," + y + ")");
        }
        // 末到终点
        else {
            // 标记坐标为(x, y)位置已经被访问过了
            visited[x][y] = true;
            result.add("(" + x + "," + y + ")");

            // 向前走
            wayfinding(matrix, x, y + 1, visited, find, result);
            // 如果已经找到就结束
            if (find[0]) {
                return;
            }

            // 向上走
            wayfinding(matrix, x - 1, y, visited, find, result);
            // 如果已经找到就结束
            if (find[0]) {
                return;
            }

            // 向后走
            wayfinding(matrix, x, y - 1, visited, find, result);
            // 如果已经找到就结束
            if (find[0]) {
                return;
            }

            // 向下走
            wayfinding(matrix, x + 1, y, visited, find, result);
            // 如果已经找到就结束
            if (find[0]) {
                return;
            }

            // 还原
            visited[x][y] = false;
            result.remove(result.size() - 1);
        }


    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值